import CommonUtil from '../utils/common'
import ArrayUtil from '../utils/array'
import { cloneDeep, omitBy } from 'lodash'
import URLUtil from '../utils/url'
import clone from 'clone'

export default (dataList, router, buildMicroAppRoute) => {
  let { routeMap, dynamic } = router.getRouteConfig('pc'),
    actionMap = {}, menuList = [],
    map = {}, routeList = [], routePathMap = {},
    routerPath = []

  // 缓存按钮权限
  dataList.map(data => {
    if (data.type === '3') {
      actionMap[data.parentId] = actionMap[data.parentId] || []
      actionMap[data.parentId].push(data.code.split(':').pop())
    }
  })

  menuList = dataList.map(data => {
    let menu = {
      id: data.id,
      parentId: data.parentId,
      meta: {
        id: data.id,
        parentId: data.parentId,
        title: data.name,
        hidden: data.type == '3' ? true : CommonUtil.toBool(data.hidden),
        icon: data.icon,
        type: data.type
      }
    }

    let query = null,
      url = null
    if (data.uri) {
      query = URLUtil.getURLParams(data.uri) || {}
      url = data.uri.split('?')[0]
    }

    url && (menu.path = url)
    data.target == '3' && (menu.meta.target = '_blank')
    data.target == '2' && (menu.meta.target = 'iframe')
    menu.query = query || {}

    // 构建微应用
    if (data.microAppName && data.microAppURL) {
      menu.meta.microAppName = data.microAppName
      menu.meta.microAppURL = data.microAppURL
      if (!routerPath.includes(menu.meta.microAppName) && buildMicroAppRoute) {
        const route = buildMicroAppRoute({
          name: menu.meta.microAppName,
          url: menu.meta.microAppURL,
          meta: menu.meta
        })
        route.meta.authorize = []
        routeList.push(route)
        routerPath.push(menu.meta.microAppName)
      }
      menu.path.startsWith('/') && (menu.path = menu.path.substring(1))
      menu.path = `/${menu.meta.microAppName}/${menu.path}`
      return menu
    }

    // 从本地路由配置中获取路由
    let route = routeMap[url] || dynamic[url]

    if (route) {
      route = clone(route)

      // 合并菜单 meta 到路由
      CommonUtil.merge(route.meta, menu.meta)

      if (menu.query.menuId) {
        route.path = `${url}/${menu.query.menuId}`
        menu.path = route.path
        route.meta.realPath = url
      }

      // 添加功能权限
      route.meta.authorize = actionMap[route.meta.id] || []

      // 去除子路由中没有 path 的子节点（功能按钮），或标记为绝对路径的子路由
      route.children = route.children?.filter(child => child.path && !child.meta.absolute) || []

      // 转存在 path 路径上配置的参数
      route.query = query || {}

      map[route.meta.id] = route
      routeList.push(route)
      routerPath.push(route.path)
    } else if (url && !routerPath.includes(url)) {
      // 本地路由配置中未找到，且返回数据中存在路由地址，则生成新的路由
      route = {
        path: menu.path,
        component: router.getView(data.component),
        meta: cloneDeep(menu.meta),
        query: query,
        children: []
      }

      // 添加功能权限
      route.meta.authorize = actionMap[route.meta.id] || []

      map[route.meta.id] = route
      routeList.push(route)
      routerPath.push(menu.path)
    }
    return menu
  })

  // array 转 tree
  const { nodeList, nodeMap } = ArrayUtil.toTree(menuList, 'id', 'parentId')

  // 构建本地注册的路由及菜单
  const roots = router.getRoots(),
    root = roots.find(item => item.path === '/' || item.path === ''),
    localMenuList = buildLocalRouteMenu(root.children)

  localMenuList.map((menu, index) => {
    nodeList.splice(index, 0, menu)
  })

  // 如路由地址为其他根路由地址开头的，则将路由添加到对应根路由的 children 中
  roots.map(root => {
    root.children = root.children || []

    root.children.map(child => {
      child.meta._parent && child.meta.absolute && child.meta._parent.children.splice(child.meta._parent.children.indexOf(child), 1)
    })

    if (root.path == '/') {
      return
    }
    Object.keys(map).map(id => {
      const route = map[id]
      if (route.path.startsWith(`${root.path}/`) && route.path != root.path) {
        root.children.push(route)
        routeList.splice(routeList.indexOf(route), 1)
      }
    })
  })

  // 追加新的权限路由到 root 路由下
  root.children = root.children.concat(routeList.filter(route => route.meta.absolute || !route._parent))

  // 动态路由中的静态路由
  Object.keys(dynamic).map(path => {
    if (dynamic[path].meta?.static) {
      root.children.push(dynamic[path])
    }
  })

  // 设置根路由的默认重定向地址
  nodeList.find(node => {
    return setDefaultRedirect(root, node)
  })
  return { roots, menuList: nodeList, menuMap: nodeMap }
}

/**
 * 构建本地注册的路由菜单
 * @param {*} router
 */
function buildLocalRouteMenu (children) {
  const menuList = children.map(child => {
    child.meta.id = child.path
    child.meta.parentId = child.meta._parent?.path || null

    // 构建菜单数据
    return {
      id: child.path,
      parentId: child.meta._parent?.path || null,
      path: child.path,
      meta: {
        id: child.path,
        parentId: child.meta._parent?.path || null,
        ...cloneDeep(child.meta)
      }
    }
  })
  const { nodeList, nodeMap } = ArrayUtil.toTree(menuList, 'id', 'parentId')
  // 只返回没有上级节点的菜单数据
  return nodeList
}

function setDefaultRedirect (root, menu) {
  if (root.redirect) {
    return true
  }
  if (!menu.hidden && menu.path) {
    root.redirect = menu.path
    return true
  } else if (menu.children) {
    menu.children.find(child => {
      return setDefaultRedirect(root, child)
    })
  }
  return false
}

function getDefaultRedirect (route) {

}

function hideChildren (routeList) {
  routeList.map(r => {
    if (r.children) {
      if (r.children.length == 0) {
        r.hideChildrenInMenu = true
      } else {
        // 下级节点不为功能菜单并且下级节点没有要显示的菜单
        const c = r.children.find(c => {
          return c.meta?.type != '3' && !c.hidden
        })
        !c && (r.hideChildrenInMenu = true)
      }
    }
    hideChildren(r.children || [])
  })
}
